﻿// HKTargetDetection.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <stdio.h>
#include <iostream>
#include "Windows.h"
#include "HCNetSDK.h"
using namespace std;

//时间解析宏定义
#define GET_YEAR(_time_)      (((_time_)>>26) + 2000) 
#define GET_MONTH(_time_)     (((_time_)>>22) & 15)
#define GET_DAY(_time_)       (((_time_)>>17) & 31)
#define GET_HOUR(_time_)      (((_time_)>>12) & 31) 
#define GET_MINUTE(_time_)    (((_time_)>>6)  & 63)
#define GET_SECOND(_time_)    (((_time_)>>0)  & 63)

int G_PIC_INDEX = 0;

BOOL CALLBACK MessageCallback(LONG lCommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen, void* pUser)
{
    switch(lCommand) 
    {       
        case COMM_VCA_ALARM: //智能检测通用报警
        {
            if(pAlarmInfo == NULL)
            {
                return FALSE;                
            }
            printf("智能检测通用报警, 报警数据内容：%s\n", pAlarmInfo);
        }
        break;
        case COMM_ISAPI_ALARM: //智能检测通用报警
        {
            if(pAlarmInfo == NULL)
            {
                return FALSE;                
            }
            NET_DVR_ALARM_ISAPI_INFO struISAPIInfo = {0};
            memcpy(&struISAPIInfo, pAlarmInfo, sizeof(NET_DVR_ALARM_ISAPI_INFO));
            printf("智能检测通用报警, 数据类型：%d, 数据内容:%s\n", struISAPIInfo.byDataType,struISAPIInfo.pAlarmData);
			printf("智能检测通用报警, 图片数量：%d\n", struISAPIInfo.byPicturesNumber);
			
			FILE *fresult;
			fopen_s(&fresult, "result.txt", "a+");
			if (fresult)
			{
				fwrite(struISAPIInfo.pAlarmData, sizeof(char), strlen(struISAPIInfo.pAlarmData), fresult);
				fclose(fresult);
			}

			G_PIC_INDEX++;
			for (int i = 0; i < struISAPIInfo.byPicturesNumber; i++)
			{
				LPNET_DVR_ALARM_ISAPI_PICDATA picdata = (LPNET_DVR_ALARM_ISAPI_PICDATA)struISAPIInfo.pPicPackData + i;
				printf("智能检测通用报警, 图片名：%s\n", picdata->szFilename);
				printf("智能检测通用报警, 图片大小：%d\n", picdata->dwPicLen);
				printf("智能检测通用报警, 图片格式：%d\n", picdata->byPicType);

				char fnamePic[128];
				sprintf_s(fnamePic, 128, "%d_%s.jpg", G_PIC_INDEX, picdata->szFilename);

				FILE *fpic;
				fopen_s(&fpic, fnamePic, "wb");
				if (!fpic)
					continue;
				fwrite(picdata->pPicData, sizeof(BYTE), picdata->dwPicLen, fpic);
				fclose(fpic);
			}

		}
        break;
        default:
        printf("其他报警，报警信息类型: 0x%x\n", lCommand);
        break;
    }

    
    return TRUE;
}

void main() {
    //---------------------------------------
    // 初始化
    NET_DVR_Init();
    //设置连接时间与重连时间
    NET_DVR_SetConnectTime(2000, 1);
    NET_DVR_SetReconnect(10000, true);

    //SDK本地参数配置
    NET_DVR_LOCAL_GENERAL_CFG struGeneralCfg = {0};
    struGeneralCfg.byAlarmJsonPictureSeparate = 1; //控制JSON透传报警数据和图片是否分离，0-不分离，1-分离（分离后走COMM_ISAPI_ALARM回调返回）
    
    if (!NET_DVR_SetSDKLocalCfg(NET_DVR_LOCAL_CFG_TYPE_GENERAL, &struGeneralCfg))
    {
        printf("NET_DVR_SetSDKLocalCfg, error code: %d\n", NET_DVR_GetLastError());
        NET_DVR_Cleanup(); 
        return;
    }

    //---------------------------------------
    // 注册设备
    LONG lUserID;

    //登录参数，包括设备地址、登录用户、密码等
    NET_DVR_USER_LOGIN_INFO struLoginInfo = {0};
    struLoginInfo.bUseAsynLogin = 0; //同步登录方式
	strcpy_s((char*)struLoginInfo.sDeviceAddress, sizeof(struLoginInfo.sDeviceAddress), "10.2.73.66"); //设备IP地址
	struLoginInfo.wPort = 8000; //设备服务端口
    strcpy_s((char*)struLoginInfo.sUserName,sizeof(struLoginInfo.sUserName), "admin"); //设备登录用户名
    strcpy_s((char*)struLoginInfo.sPassword,sizeof(struLoginInfo.sPassword), "glodon123"); //设备登录密码
  
    //设备信息, 输出参数
    NET_DVR_DEVICEINFO_V40 struDeviceInfoV40 = {0};

    lUserID = NET_DVR_Login_V40(&struLoginInfo, &struDeviceInfoV40);
    if (lUserID < 0)
    {
        printf("Login failed, error code: %d\n", NET_DVR_GetLastError());
        NET_DVR_Cleanup();
        return;
    }

	printf("Login success\n");
  
    //设置报警回调函数
    NET_DVR_SetDVRMessageCallBack_V31(MessageCallback, NULL);
  
    //启用布防
    LONG lHandle;
    NET_DVR_SETUPALARM_PARAM  struAlarmParam={0};
    struAlarmParam.dwSize=sizeof(struAlarmParam);
    struAlarmParam.byAlarmTypeURL = 1 << 1; //报警图片数据类型，bit1-报警类型为COMM_VCA_ALARM对应的json报警数据中图片数据长传类型，0- 二进制传输，1- URL传输
    //其他报警布防参数不需要设置，不支持

    lHandle = NET_DVR_SetupAlarmChan_V41(lUserID, & struAlarmParam);
    if (lHandle < 0)
    {
        printf("NET_DVR_SetupAlarmChan_V41, error code: %d\n", NET_DVR_GetLastError());
        NET_DVR_Logout(lUserID);
        NET_DVR_Cleanup(); 
        return;
    }
  
	while(1)
	{
		Sleep(50000); //等待过程中，如果设备上传报警信息，在报警回调函数里面接收和处理报警信息
	}
    
    //撤销布防上传通道
    if (!NET_DVR_CloseAlarmChan_V30(lHandle))
    {
        printf("NET_DVR_CloseAlarmChan_V30, error code: %d\n", NET_DVR_GetLastError());
        NET_DVR_Logout(lUserID);
        NET_DVR_Cleanup(); 
        return;
    }
  
    //注销用户
    NET_DVR_Logout(lUserID);
    //释放SDK资源
    NET_DVR_Cleanup();
    return;
}

